package com.yuanli.card.manage.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yuanli.card.enumeration.CardPeriodEnum;
import com.yuanli.card.enumeration.CardStatusEnum;
import com.yuanli.card.exception.ServiceException;
import com.yuanli.card.pojo.CardFlow;
import com.yuanli.card.utils.*;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

import java.io.IOException;
import java.text.ParseException;
import java.util.*;

/**
 * Created by layne on 2018/12/28.
 */
public class ShenZhenChannel extends AbstractAbility {
    /**
     * msisdns String 号码 多个半角逗号分隔，最多1000个；
     * optType Integer 1:停机 2:开机
     *
     * @param ability
     * @param paramsIn
     * @return
     */
    @Override
    public List<String> batchStopOpen(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        Map<String, String> signMap = new HashMap<>();
        ability.getParams().forEach((k, v) -> signMap.put(k, String.valueOf(v)));
        String transId = getTransId((String) ability.getParams().get("groupId"));

        List<String> iccids = (List<String>) paramsIn.get("iccids");
        StringBuilder sb = new StringBuilder();
        iccids.forEach(s -> sb.append(s + ","));
        String iccidsStr = sb.substring(0, sb.length() - 1);
        signMap.put("transID", transId);
        signMap.put("iccids", iccidsStr);
        signMap.put("optType", (String) paramsIn.get("optType"));
        String sign = SzApiUtils.sign(signMap, Arrays.asList("groupId", "appSecret"),
                (String) ability.getParams().get("appSecret"));
        Map<String, String> params = new HashMap<>();
        params.put("transID", transId);
        params.put("format", (String) ability.getParams().get("format"));
        params.put("v", (String) ability.getParams().get("v"));
        params.put("appKey", (String) ability.getParams().get("appKey"));
        params.put("method", (String) ability.getParams().get("method"));
        params.put("sign", sign);
        params.put("iccids", iccidsStr);
        params.put("optType", (String) paramsIn.get("optType"));

        String invoke = invoke(String.class, ability.getUrl(), ability.getMediaType(), ability.getMethod(), params);
        String res = decrypt(invoke);

        logger.info("移动报文:{}", res);
        ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();
        JsonNode resNode = null;
        try {
            resNode = mapper.readValue(res, JsonNode.class);
        } catch (Exception e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        String code = resNode.get("code").asText("没有获取到错误码");
        if (!"0".equals(code)) {
            String error = resNode.get("error").asText("没有获取到错误信息");
            logger.error("移动接口返回报文状态:" + code + ",错误信息:" + error);
            throw new ServiceException("移动接口返回报文异常");
        }
        Map<String, CardPeriodEnum> resultMap = new HashMap<>();
        String dataText = resNode.get("data").asText();
        if (dataText.startsWith("\"")) {
            dataText = dataText.substring(1);
        }
        if (dataText.endsWith("\"")) {
            dataText = dataText.substring(0, dataText.length() - 1);
        }
        JsonNode dataNode = null;
        try {
            dataNode = mapper.readValue(dataText, JsonNode.class);
        } catch (IOException e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        //业务办理订单号,用于查询结果
        String orderNo = dataNode.get("result").get("orderNo").asText();
        return null;
    }

    @Override
    public void cancelTestPeriod(ChannelInterface.AbilitiesBean.AbilityBean abilityBean, Map<String, Object> paramsIn) {

    }

    private String getTransId(String groupId) {
        return groupId + DateUtils.simpleDateFormat(DateUtils.YYYYMMDDHHMMSSMI).format(new Date()) + CommonUtil.randomNumber(4);
    }

    @Override
    public CardStatusEnum queryUserStatus(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        Map<String, String> signMap = new HashMap<>();
        signMap.forEach((k, v) -> signMap.put(v, String.valueOf(v)));
        String transId = getTransId((String) ability.getParams().get("groupId"));
        signMap.put("iccids", (String) paramsIn.get("iccids"));
        String sign = SzApiUtils.sign(signMap, Arrays.asList("groupId"),
                (String) ability.getParams().get("appsecret"));
        Map<String, String> params = new HashMap<>();
        params.put("transID", transId);
        params.put("format", (String) ability.getParams().get("format"));
        params.put("v", (String) ability.getParams().get("v"));
        params.put("appKey", (String) ability.getParams().get("appKey"));
        params.put("sign", sign);
        params.put("iccids", (String) paramsIn.get("iccids"));
        Object invoke = invoke(String.class, ability.getUrl(), ability.getMediaType(), ability.getMethod(), params);
        return null;
    }

    @Override
    public Map<String, Integer> batchQueryGprsStatus(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        return super.batchQueryGprsStatus(ability, paramsIn);
    }

    /**
     * 状态：
     * test：测试期；
     * silent：沉默期；
     * inventory：库存期；
     * normal：正使用；
     * stop：停机；
     * preclose：销户；
     * bespeakClose：预约销户。
     *
     * @param ability
     * @param paramsIn 传入参数
     * @return iccid -> 卡的生命周期
     */
    @Override
    public Map<String, CardPeriodEnum> batchQueryCardLifeCycle(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        Map<String, String> signMap = new HashMap<>();
        ability.getParams().forEach((k, v) -> signMap.put(k, String.valueOf(v)));
        String transId = getTransId((String) ability.getParams().get("groupId"));

        List<String> iccids = (List<String>) paramsIn.get("iccids");
        StringBuilder sb = new StringBuilder();
        iccids.forEach(s -> sb.append(s + ","));
        String iccidsStr = sb.substring(0, sb.length() - 1);
        signMap.put("transID", transId);
        signMap.put("iccids", iccidsStr);
        String sign = SzApiUtils.sign(signMap, Arrays.asList("groupId", "appSecret"),
                (String) ability.getParams().get("appSecret"));
        Map<String, String> params = new HashMap<>();
        params.put("transID", transId);
        params.put("format", (String) ability.getParams().get("format"));
        params.put("v", (String) ability.getParams().get("v"));
        params.put("appKey", (String) ability.getParams().get("appKey"));
        params.put("method", (String) ability.getParams().get("method"));
        params.put("sign", sign);
        params.put("iccids", iccidsStr);
        String invoke = invoke(String.class, ability.getUrl(), ability.getMediaType(), ability.getMethod(), params);
        String res = decrypt(invoke);

        logger.info("移动报文:{}", res);
        ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();
        JsonNode resNode = null;
        try {
            resNode = mapper.readValue(res, JsonNode.class);
        } catch (Exception e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        String code = resNode.get("code").asText("没有获取到错误码");
        if (!"0".equals(code)) {
            String error = resNode.get("error").asText("没有获取到错误信息");
            logger.error("移动接口返回报文状态:" + code + ",错误信息:" + error);
            throw new ServiceException("移动接口返回报文异常");
        }
        Map<String, CardPeriodEnum> resultMap = new HashMap<>();
        String dataText = resNode.get("data").asText();
        if (dataText.startsWith("\"")) {
            dataText = dataText.substring(1);
        }
        if (dataText.endsWith("\"")) {
            dataText = dataText.substring(0, dataText.length() - 1);
        }
        JsonNode dataNode = null;
        try {
            dataNode = mapper.readValue(dataText, JsonNode.class);
        } catch (IOException e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        JsonNode msisdnInfoList = dataNode.get("statusList").get("list");
        Iterator<JsonNode> iterator = msisdnInfoList.iterator();
        while (iterator.hasNext()) {
            JsonNode statusNode = iterator.next();
            String code1 = statusNode.get("code").asText();
            String iccid = statusNode.get("iccid").asText();
            String msisdn = statusNode.get("msisdn").asText();
            String status = statusNode.get("status").asText();
            String statusTime = statusNode.get("statusTime").asText();
            resultMap.put(iccid, CardPeriodEnum.valueOf(status));
        }
        return resultMap;
    }

    @Override
    public Map<String, CardFlow> batchGprsUsedByDate(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        return super.batchGprsUsedByDate(ability, paramsIn);
    }

    @Override
    public Map<String, CardFlow> queryGprsShare(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        return super.queryGprsShare(ability, paramsIn);
    }

    @Override
    public Map<String, CardFlow> batchQueryGprsShare(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        return super.batchQueryGprsShare(ability, paramsIn);
    }

    /**
     * @param ability
     * @param paramsIn
     * @return
     */
    @Override
    public Map<String, CardFlow> batchQueryRealtimeGprsInfo(ChannelInterface.AbilitiesBean.AbilityBean ability, Map<String, Object> paramsIn) {
        Map<String, String> signMap = new HashMap<>();
        ability.getParams().forEach((k, v) -> signMap.put(k, String.valueOf(v)));
        String transId = getTransId((String) ability.getParams().get("groupId"));

        List<String> iccids = (List<String>) paramsIn.get("iccids");
        StringBuilder sb = new StringBuilder();
        iccids.forEach(s -> sb.append(s + ","));
        String iccidsStr = sb.substring(0, sb.length() - 1);
        signMap.put("transID", transId);
        signMap.put("iccids", iccidsStr);
        String sign = SzApiUtils.sign(signMap, Arrays.asList("groupId", "appSecret"),
                (String) ability.getParams().get("appSecret"));
        Map<String, String> params = new HashMap<>();
        params.put("transID", transId);
        params.put("format", (String) ability.getParams().get("format"));
        params.put("v", (String) ability.getParams().get("v"));
        params.put("appKey", (String) ability.getParams().get("appKey"));
        params.put("method", (String) ability.getParams().get("method"));
        params.put("sign", sign);
        params.put("iccids", iccidsStr);
        String invoke = invoke(String.class, ability.getUrl(), ability.getMediaType(), ability.getMethod(), params);
        String res = decrypt(invoke);
        //SZ移动数据不规范,导致爸爸要多谢几百行代码 FXXX
        ObjectMapper mapper = Jackson2ObjectMapperBuilder.json().build();
        JsonNode resNode = null;
        try {
            resNode = mapper.readValue(res, JsonNode.class);
        } catch (Exception e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        String code = resNode.get("code").asText("没有获取到错误码");
        if (!"0".equals(code)) {
            String error = resNode.get("error").asText("没有获取到错误信息");
            logger.error("移动接口返回报文状态:" + code + ",错误信息:" + error);
            throw new ServiceException("移动接口返回报文异常");
        }
        Map<String, CardFlow> resultMap = new HashMap<>();
        String dataText = resNode.get("data").asText();
        if (dataText.startsWith("\"")) {
            dataText = dataText.substring(1);
        }
        if (dataText.endsWith("\"")) {
            dataText = dataText.substring(0, dataText.length() - 1);
        }
        JsonNode dataNode = null;
        try {
            dataNode = mapper.readValue(dataText, JsonNode.class);
        } catch (IOException e) {
            logger.error("Json解析异常", e);
            throw new ServiceException("Json解析异常");
        }
        JsonNode msisdnInfoList = dataNode.get("msisdnInfoList").get("list");
        Iterator<JsonNode> iterator = msisdnInfoList.iterator();
        while (iterator.hasNext()) {
            JsonNode cardInfoNode = iterator.next();
            String code1 = cardInfoNode.get("code").asText();
            String iccid = cardInfoNode.get("iccid").asText();
            String msisdn = cardInfoNode.get("msisdn").asText();
            JsonNode apnListNode = cardInfoNode.get("apnList").get("list");
            Iterator<JsonNode> apnInfoNodeIterator = apnListNode.iterator();
            while (apnInfoNodeIterator.hasNext()) {
                JsonNode apnInfoNode = apnInfoNodeIterator.next();
                String apnName = apnInfoNode.get("apnName").asText();
                String extraPkgFlow = apnInfoNode.get("extraPkgFlow").asText();
                String lastFlowTime = apnInfoNode.get("lastFlowTime").asText();
                String restFlow = apnInfoNode.get("restFlow").asText();
                String totalFlow = apnInfoNode.get("totalFlow").asText();
                String usedFlow = apnInfoNode.get("usedFlow").asText();
                JsonNode pkgInfoListNode = apnInfoNode.get("pkgInfoList").get("list");
                Iterator<JsonNode> pkgInfoListNodeIterator = pkgInfoListNode.iterator();
                while (pkgInfoListNodeIterator.hasNext()) {
                    JsonNode pkgInfoNode = pkgInfoListNodeIterator.next();
                    String pkgCode = pkgInfoNode.get("pkgCode").asText();
                    String pkgEfftDate = pkgInfoNode.get("pkgEfftDate").asText();
                    String pkgExpireDate = pkgInfoNode.get("pkgExpireDate").asText();
                    String pkgName = pkgInfoNode.get("pkgName").asText();
                    String restFlow1 = pkgInfoNode.get("restFlow").asText();
                    String subSprodId = pkgInfoNode.get("subSprodId").asText();
                    String totalFlow1 = pkgInfoNode.get("totalFlow").asText();
                    String totalUsedFlow = pkgInfoNode.get("totalUsedFlow").asText();
                    String usedFlow1 = pkgInfoNode.get("usedFlow").asText();
                    CardFlow cardFlow = new CardFlow()
                            .setComboName(pkgName)
                            .setUsed(Double.valueOf(usedFlow1))
                            .setTotal(Double.valueOf(totalFlow1))
                            .setLeft(Double.valueOf(restFlow1))
                            .setIccid(iccid);
                    try {
                        cardFlow.setComboDate(DateUtils.simpleDateFormat(DateUtils.YYYYMMDDHHMMSS_1).parse(pkgEfftDate));
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }

                    resultMap.put(iccid, cardFlow);
                }
            }

        }
        return resultMap;
    }

    /**
     * 解密深圳移动报文
     *
     * @param tobeDecrypt 待解密报文
     * @return 解密后报文
     */
    private String decrypt(String tobeDecrypt) {
        return DESUtils.decrypt(tobeDecrypt, "1024ddc09b3edc7a6256267f");
    }
}